#ifndef __AT24CXX_H__
#define __AT24CXX_H__

#include "iic.h"
#include <stdint.h>

/*设备在线检测标志字*/
#define EEPROM_LAST_ADDR_CHECK_DATA 0xAA

/**
 * @brief 设备型号枚举类型定义
 */
typedef enum
{
    AT24C01 = 127,
    AT24C02 = 255,
    AT24C04 = 511,
    AT24C08 = 1023,
    AT24C16 = 2047,
    AT24C32 = 4095,
    AT24C64 = 8191,
    AT24C128 = 16383,
    AT24C256 = 32767,
    AT24C512 = 65535
} at24cxx_chiptype_t;
/**
 * @brief EEPROM 设备速度等级枚举类型定义
 */
typedef enum
{
    I2cStandardSpeed = 100000, /*100K*/
    I2cHighSpeed = 400000,     /*400K*/
    I2cSuperSpeed = 1000000,   /*1M*/
} at24cxx_speedlevel_t;
/**
 * @brief EEPROM 设备结构体定义
 */
typedef struct
{
    at24cxx_speedlevel_t eespdlvl; /*速度等级*/
    at24cxx_chiptype_t eetype;     /*EEPROM型号*/
    uint16_t pagenum;              /*页数目*/
    uint8_t eedevaddr;             /*设备地址*/
    uint8_t pagesize;              /*页字节数*/
    uint8_t wrdlyms;               /*跨页写入延时时间，单位ms，默认值10 */
    iic_t *pi2c;
} at24cxx_t;

int32_t at24cxx_check(at24cxx_t *p);
int32_t at24cxx_init(at24cxx_t *p, at24cxx_chiptype_t, uint8_t, at24cxx_speedlevel_t, iic_t *);
int32_t at24cxx_readonebyte(at24cxx_t *p, uint16_t readaddr, uint8_t *rbuf);
int32_t at24cxx_writeonebyte(at24cxx_t *p, uint16_t writeaddr, uint8_t datatowrite);
int32_t at24cxx_write(at24cxx_t *p, uint16_t writeaddr, uint8_t *pbuffer, uint32_t numtowrite);
int32_t at24cxx_read(at24cxx_t *p, uint16_t readaddr, uint8_t *pbuffer, uint32_t numtoread);

/*
demo

#define BIT_BAND(addr,bit)   *(volatile unsigned long*)(((uint32_t)(addr) & 0xF0000000) +\
                0x2000000 + (((uint32_t)(addr) & 0xFFFFF)<<5) + ((bit)<<2))
static void delay_us(uint32_t l)
{
    while (l--)
    {
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
        __NOP();
    }
}
static void wr_i2c_scl(bool st)
{
    BIT_BAND(&GPIOD->ODR, 3) = st;
}
static void wr_i2c_sda(bool st)
{
    BIT_BAND(&GPIOB->ODR, 4) = st;
}
static bool rd_i2c_sda(void)
{
    return BIT_BAND(&GPIOB->IDR, 4);
}
iic_iodrv_t iic_iodrv = {
    .wrscl = wr_i2c_scl,
    .wrsda = wr_i2c_sda,
    .rdsda = rd_i2c_sda,
    .dlyus = delay_us};
//测试方法：测试使用的EEPROM为AT24C512，在eeprom第一页的中间地址开始写入一页容量的数据。
//          前64字节写入第0页 后64字节写入到第1页
//目    的：在测试读写函数功能正常的同时，也测试了跨页写入功能。
void main()
{
    #define EE_TEST_SIZE 128
    #define EE_TEST_VALUE 0xAA
    uint8_t ee_test[EE_TEST_SIZE];
    uint8_t ee_testr[EE_TEST_SIZE];
    //定义I2C总线设备
    iic_t iic;
    //定义EEPROM存储设备
    at24cxx_t at24c512;
    //初始化I2C设备
    iic_regsiter(&iic, &iic_iodrv);
    //初始化EEPROM设备
    at24cxx_init(&at24c512, AT24C512, 0x50, I2cStandardSpeed, &iic);
    //检测设备
    do{
        HAL_Delay(500);
    }while(at24cxx_check(&at24c512));
    //设定测试数组值
    memset(ee_test, EE_TEST_VALUE, sizeof(ee_test));
    //写入到EEPROM
    at24cxx_write(&at24c512, at24c512.pagesize - EE_TEST_SIZE / 2, ee_test, sizeof(ee_test));
    //延时20ms
    HAL_Delay(20);
    //读取EEPROM
    at24cxx_read(&at24c512, at24c512.pagesize - EE_TEST_SIZE / 2, ee_testr, sizeof(ee_testr));
    //检测数据一致性
    if (0 == memcmp(ee_test, ee_testr, sizeof(ee_testr)))
    {
        // 成功
    }
    else
    {
        // 失败
    }
}
*/
#endif
